home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_319 / cnewssrc / cnews.src.lzh / relay / sys.c < prev    next >
C/C++ Source or Header  |  1989-06-27  |  8KB  |  323 lines

  1. /*
  2.  * news sys file reading functions
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #ifndef AMIGA
  8. #  include <sys/types.h>
  9. #  include <sys/stat.h>
  10. #endif
  11. #include "libc.h"
  12. #include "fgetmfs.h"
  13. #include "news.h"
  14. #include "config.h"
  15. #include "system.h"
  16.  
  17. #define BTCHDIR "out.going/"    /* prefix of relative batch file name */
  18. #define BTCHPFX BTCHDIR            /* prefix of default batch file name */
  19. #define BTCHSFX "/togo"            /* suffix of same */
  20. #define CMDPFX "uux - -r -z "    /* prefix of default command */
  21. #define CMDSFX "!rnews"            /* suffix of same */
  22.  
  23. /* private */
  24. static FILE *fp = NULL;            /* stream for ctlfile(filerelname) */
  25. static char filerelname[] = "sys";    /* filename relative to $NEWSCTL */
  26.  
  27. /* forward decls */
  28. FORWARD char *parsecolon(), *reparse();
  29. FORWARD void readsys(), parsesysln(), parse(), parseflags();
  30.  
  31. /* exports */
  32. struct system *firstsys = NULL;    /* cache: 1st sys of in-core sys file */
  33. struct system *currsys = NULL;    /* current system */
  34.  
  35. /* imports */
  36. extern boolean justone;
  37. extern struct system *mysysincache();
  38. extern void rewsys(), remmysys(), freecurrsys();
  39.  
  40. struct system *
  41. oursys()            /* return our sys entry */
  42. {
  43.     register struct system *sys = mysysincache();
  44.     static struct system fakesys;
  45.  
  46.     if (sys == NULL) {
  47.         rewsys(fp);
  48.         while ((sys = nextsys()) != NULL &&
  49.             !STREQ(sys->sy_name, hostname()))
  50.             ;
  51.         if (sys == NULL) {
  52.             /* no entry: cook one up; no need to malloc members */
  53.             fakesys.sy_name = hostname();
  54.             fakesys.sy_excl = NULL;
  55.             fakesys.sy_ngs = "all";
  56.             fakesys.sy_distr = "all";
  57.             fakesys.sy_flags = 0;
  58.             fakesys.sy_lochops = 0;
  59.             fakesys.sy_cmd = "";
  60.             fakesys.sy_next = NULL;
  61.             sys = &fakesys;
  62.         }
  63.         remmysys(sys);            /* for future reference */
  64.     }
  65.     return sys;
  66. }
  67.  
  68. /*
  69.  * Return the next sys entry, which may span multiple lines.
  70.  * Returned pointer points at a static struct whose members
  71.  * point at static storage.
  72.  *
  73.  * It would be clearer to rewrite the justone/nextsys/readsys dance
  74.  * to get rid of justone, but I haven't the energy.  Sorry.  Beware that
  75.  * justone is set in either ../libbig/sys.fast.c or ../libsmall/sys.slow.c.
  76.  */
  77. struct system *
  78. nextsys()
  79. {
  80.     struct system *retsys;
  81.  
  82.     if (firstsys == NULL && fp == NULL)
  83.         if ((fp = fopenwclex(ctlfile(filerelname), "r")) == NULL)
  84.             return NULL;
  85.     if (fp != NULL && firstsys == NULL)
  86.         readsys();
  87.     retsys = currsys;
  88.     if (currsys != NULL)
  89.         currsys = currsys->sy_next;
  90.     return retsys;
  91. }
  92.  
  93. /*
  94.  * If justone, read one entry; else read whole sys file (done once only).
  95.  * Ignores '#' comments and blank lines; uses cfgetms to read possibly-
  96.  * continued lines of arbitrary length.
  97.  */
  98. STATIC void
  99. readsys()
  100. {
  101.     register char *sysline;
  102.  
  103.     if (justone)
  104.         freecurrsys();
  105.     else
  106.         rewind(fp);
  107.     while ((sysline = cfgetms(fp)) != NULL) {
  108.         if (sysline[0] != '#' && sysline[0] != '\n')
  109.             parsesysln(sysline);
  110.         free(sysline);
  111.         if (justone && firstsys != NULL) {    /* parsed an entry */
  112.             firstsys = NULL;
  113.             return;
  114.         }
  115.     }
  116.     (void) nfclose(fp);
  117.     fp = NULL;
  118.     rewsys(fp);
  119. }
  120.  
  121. static char *curr, *next;            /* parsing state */
  122.  
  123. /*
  124.  * Parse (and modify) sysline into *currsys, which is malloced here
  125.  * and freed iff "justone", in readsys(), see freecursys().
  126.  *
  127.  * Side-effect: sysline has a trailing newline removed.
  128.  */
  129. STATIC void
  130. parsesysln(sysline)
  131. register char *sysline;
  132. {
  133.     register struct system *sysp =(struct system *)nemalloc(sizeof *sysp);
  134.     char *flagstring;
  135.  
  136.     trim(sysline);
  137.     next = sysline;
  138.     parse(&sysp->sy_name);
  139.     parse(&sysp->sy_ngs);
  140.     parse(&flagstring);
  141.     parse(&sysp->sy_cmd);
  142.     /* could check for extra fields here */
  143.  
  144.     parseflags(flagstring, sysp);
  145.     free(flagstring);        /* malloced by parse */
  146.     sysp->sy_next = NULL;
  147.  
  148.     /* reparse for embedded slashes */
  149.     sysp->sy_excl = reparse(sysp->sy_name, '/');
  150.     sysp->sy_distr = reparse(sysp->sy_ngs, '/');
  151.     if (sysp->sy_distr == NULL)    /* default distr is ngs... */
  152.         sysp->sy_distr = sysp->sy_ngs;
  153.  
  154.     sysdeflt(sysp);            /* fill in any defaults */
  155.  
  156.     /* stash *sysp away on the tail of the current list of systems */
  157.     if (firstsys == NULL)
  158.         firstsys = sysp;
  159.     else
  160.         currsys->sy_next = sysp;
  161.     currsys = sysp;
  162. }
  163.  
  164. /*
  165.  * fill in defaults in sysp.
  166.  *
  167.  * expand a name of "ME" to hostname().
  168.  * If an empty batch file name was given, supply a default
  169.  * ($NEWSARTS/BTCHPFX system BTCHSFX).
  170.  * Prepend $NEWSARTS/BTCHDIR to relative file names.
  171.  * If an empty command was given, supply a default (uux - -r -z sys!rnews).
  172.  * (This *is* yucky and uucp-version-dependent.)
  173.  */
  174. void
  175. sysdeflt(sysp)
  176. register struct system *sysp;
  177. {
  178.     if (STREQ(sysp->sy_name, "ME")) {
  179.         free(sysp->sy_name);    /* malloced by parse */
  180.         sysp->sy_name = strsave(hostname());
  181.     }
  182.     if (sysp->sy_flags&FLG_BATCH && sysp->sy_cmd[0] == '\0') {
  183.         register char *deffile = nemalloc((unsigned) STRLEN(BTCHPFX) +
  184.             strlen(sysp->sy_name) + STRLEN(BTCHSFX) + 1);
  185.  
  186.         (void) strcpy(deffile, BTCHPFX);
  187.         (void) strcat(deffile, sysp->sy_name);
  188.         (void) strcat(deffile, BTCHSFX);
  189.         free(sysp->sy_cmd);    /* malloced by parse */
  190.         sysp->sy_cmd = strsave(fullartfile(deffile));
  191.         free(deffile);
  192.     }
  193.     if (sysp->sy_flags&FLG_BATCH && sysp->sy_cmd[0] != FNDELIM) {
  194.         register char *absfile = nemalloc((unsigned) STRLEN(BTCHDIR) +
  195.             strlen(sysp->sy_cmd) + 1);
  196.  
  197.         (void) strcpy(absfile, BTCHDIR);
  198.         (void) strcat(absfile, sysp->sy_cmd);
  199.         free(sysp->sy_cmd);    /* malloced by parse */
  200.         sysp->sy_cmd = strsave(artfile(absfile));
  201.         free(absfile);
  202.     }
  203.     if (!(sysp->sy_flags&FLG_BATCH) && sysp->sy_cmd[0] == '\0') {
  204.         free(sysp->sy_cmd);    /* malloced by parse */
  205.         sysp->sy_cmd = nemalloc((unsigned) STRLEN(CMDPFX) +
  206.             strlen(sysp->sy_name) + STRLEN(CMDSFX) + 1);
  207.         (void) strcpy(sysp->sy_cmd, CMDPFX);
  208.         (void) strcat(sysp->sy_cmd, sysp->sy_name);
  209.         (void) strcat(sysp->sy_cmd, CMDSFX);
  210.     }
  211. }
  212.  
  213. /*
  214.  * Parse "next" to colon into malloced storage, return its ptr via "into".
  215.  * *into is freed iff "justone", in readsys(), see freecursys().
  216.  */
  217. STATIC void
  218. parse(into)
  219. register char **into;
  220. {
  221.     curr = next;
  222.     if (curr == NULL)
  223.         *into = strsave("");
  224.     else {
  225.         next = parsecolon(curr);
  226.         *into = strsave(curr);
  227.     }
  228. }
  229.  
  230. STATIC char *
  231. parsecolon(line)        /* return NULL or ptr. to byte after colon */
  232. char *line;
  233. {
  234.     register char *colon;
  235.  
  236.     INDEX(line, ':', colon);
  237.     if (colon != NULL)
  238.         *colon++ = '\0';
  239.     return colon;
  240. }
  241.  
  242. /*
  243.  * replace "delim" in "field" with a NUL and return the address of the byte
  244.  * after the NUL (the address of the second subfield), or NULL if no
  245.  * "delim" was present.
  246.  */
  247. STATIC char *
  248. reparse(field, delim)
  249. char *field;
  250. int delim;
  251. {
  252.     register char *delimp = index(field, delim);
  253.  
  254.     if (delimp != NULL)
  255.         *delimp++ = '\0';
  256.     return delimp;
  257. }
  258.  
  259. /*
  260.  * Parse sys file flags into sysp.
  261.  */
  262. STATIC void
  263. parseflags(flags, sysp)
  264. register char *flags;
  265. register struct system *sysp;
  266. {
  267.     sysp->sy_flags = 0;
  268.     sysp->sy_lochops = 0;        /* default L value */
  269.     for (; *flags != '\0'; flags++)
  270.         switch (*flags) {
  271.         case 'A':
  272.             errunlock("A news format not supported", "");
  273.             /* NOTREACHED */
  274.         case 'B':        /* mostly harmless */
  275.             break;
  276.         case 'f':
  277.             sysp->sy_flags |= FLG_BATCH|FLG_SZBATCH;
  278.             break;
  279.         case 'F':
  280.             sysp->sy_flags |= FLG_BATCH;
  281.             break;
  282.         case 'I':        /* NNTP hook: write msgids, !files */
  283.             sysp->sy_flags |= FLG_BATCH|FLG_IHAVE;
  284.             break;
  285.         case 'L':        /* Ln */
  286.             sysp->sy_flags |= FLG_LOCAL;
  287.             sysp->sy_lochops = 0;
  288.             while (isascii(flags[1]) && isdigit(flags[1])) {
  289.                 sysp->sy_lochops *= 10;
  290.                 sysp->sy_lochops += *++flags - '0';
  291.             }
  292.             break;
  293.         case 'm':        /* send only moderated groups */
  294.             sysp->sy_flags |= FLG_MOD;
  295.             break;
  296.         case 'N':
  297.             errunlock(
  298.     "The N flag is a wasteful old kludge; see the I flag instead.", "");
  299.             /* NOTREACHED */
  300.         case 'n':        /* NNTP hook: write files+msgids */
  301.             sysp->sy_flags |= FLG_BATCH|FLG_NBATCH;
  302.             break;
  303.         case 'u':        /* send only unmoderated groups */
  304.             sysp->sy_flags |= FLG_UNMOD;
  305.             break;
  306.         case 'U':        /* mostly harmless */
  307.             break;
  308.         case 'H':        /* bugger off */
  309.         case 'S':        /* bugger off */
  310.         case 'M':        /* multicast: obs., see batcher */
  311.         case 'O':        /* multicast: obs., see batcher */
  312.         default:
  313.             errunlock("unknown sys flag `%s' given", flags);
  314.             /* NOTREACHED */
  315.         }
  316. }
  317.  
  318. void
  319. rewndsys()
  320. {
  321.     rewsys(fp);
  322. }
  323.